const fs = require('fs').promises;
const path = require('path');
const sharp = require('sharp');

class ResizeImages {
  constructor(config, mainWindow) {
    this.config = config;
    this.mainWindow = mainWindow;
    this.totalFiles = 0;
    this.processedFiles = 0;
  }

  // 发送进度更新
  sendProgress(progress, message) {
    if (this.mainWindow && this.mainWindow.webContents) {
      this.mainWindow.webContents.send('progress-update', {
        type: 'resize-images',
        progress,
        message
      });
    }
  }

  // 调整单个图像大小
  async resizeImage(inputPath, outputPath) {
    try {
      // 加载图片并获取原始尺寸
      const metadata = await sharp(inputPath).metadata();
      const { width, height } = metadata;
      
      // 计算缩放比例
      const { maxWidth, maxHeight } = this.config;
      let newWidth = width;
      let newHeight = height;
      
      if (width > height && width > maxWidth) {
        // 如果宽度大于高度且超过最大宽度，则按宽度调整
        newWidth = maxWidth;
        newHeight = Math.round((height * maxWidth) / width);
      } else if (height > maxHeight) {
        // 如果高度大于或等于宽度且超过最大高度，则按高度调整
        newHeight = maxHeight;
        newWidth = Math.round((width * maxHeight) / height);
      }
      
      // 确保新的尺寸不超过目标尺寸
      newWidth = Math.min(newWidth, maxWidth);
      newHeight = Math.min(newHeight, maxHeight);
      
      // 使用 sharp 进行等比例缩放并保存结果
      const resizeOptions = {
        fit: 'inside', // 确保图像不超出指定的最大尺寸
        withoutEnlargement: true, // 不允许放大图像
        kernel: sharp.kernel.lanczos3, // 使用高质量的 Lanczos 插值算法
      };
      
      let sharpInstance = sharp(inputPath)
        .resize(newWidth, newHeight, resizeOptions)
        .sharpen(); // 应用锐化
      
      // 根据输出格式设置相应的选项
      switch (this.config.outputFormat.toLowerCase()) {
        case 'png':
          sharpInstance = sharpInstance.png({ compressionLevel: 9 });
          break;
        case 'jpg':
        case 'jpeg':
          sharpInstance = sharpInstance.jpeg({ quality: 90 });
          break;
        case 'webp':
          sharpInstance = sharpInstance.webp({ quality: 90 });
          break;
        default:
          sharpInstance = sharpInstance.png({ compressionLevel: 9 });
      }
      
      await sharpInstance.toFile(outputPath);
      
      // 更新进度
      this.processedFiles++;
      const progress = Math.round((this.processedFiles / this.totalFiles) * 100);
      this.sendProgress(progress, `已处理 ${this.processedFiles}/${this.totalFiles} 个文件`);
      
      return true;
    } catch (error) {
      console.error(`处理 ${inputPath} 时发生错误:`, error);
      throw new Error(`处理文件 ${inputPath} 失败: ${error.message}`);
    }
  }

  // 批量处理图像
  async process() {
    try {
      const { inputDir, outputDir } = this.config;
      
      // 确保输出目录存在
      await fs.mkdir(outputDir, { recursive: true });
      
      // 读取目录内容
      const files = await fs.readdir(inputDir);
      
      // 过滤出图片文件
      const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.bmp'];
      const imageFiles = files.filter(file =>
        imageExtensions.some(ext => file.toLowerCase().endsWith(ext))
      );
      
      if (imageFiles.length === 0) {
        throw new Error('目录中没有找到支持的图片文件');
      }
      
      this.totalFiles = imageFiles.length;
      this.sendProgress(0, `开始处理 ${this.totalFiles} 个图片文件`);
      
      // 对每个图片文件调用 resizeImage
      for (const file of imageFiles) {
        const inputPath = path.join(inputDir, file);
        const outputFileName = `${path.basename(file, path.extname(file))}.${this.config.outputFormat}`;
        const outputPath = path.join(outputDir, outputFileName);
        await this.resizeImage(inputPath, outputPath);
      }
      
      this.sendProgress(100, '所有图片处理完成！');
      return { success: true, message: '图片缩放完成' };
    } catch (error) {
      console.error('批量处理过程中发生错误:', error);
      this.sendProgress(0, `处理失败: ${error.message}`);
      throw error;
    }
  }
}

module.exports = ResizeImages;